// TODO: CODE REVIEW & CLEANUP!
//
// MusicFoundAlbumsScreen.xaml.cs
//

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Xml;
using HomeUX.ClientAppSupport;
using HomeUX.ClientControlSupport;
using HomeUX.Controls;
using HomeUX.Synchronization;
using HomeUX.Utilities;

namespace HomeUX.MusicClientLibrary
{

public partial class MusicFoundAlbumsScreen : UserControl
{
    MusicClientHelper _musicClientHelper;

    bool _isDirty = true;
    string _find;

    /// <summary>
    /// A <n>String.Format</n>-style format string to use for <n>HeaderTextBlock</n>.  Initialized
    /// from the design-time text value of  <n>HeaderTextBlock</n>.
    /// </summary>
    string _headerFormatString;

    // query string -- set by a "caller" before navigating here
    public string Find
    {
        get
        {
            return _find;
        }
        set
        {
            _find = value;
            _isDirty = true;
        }
    }

    public MusicFoundAlbumsScreen()
    {
        InitializeComponent();

        // initialize <_headerFormatString>
        _headerFormatString = HeaderTextBlock.Text;

        Loaded += MusicFoundAlbumsScreen_Loaded;
        GotFocus += MusicFoundAlbumsScreen_GotFocus;
    }

    void MusicFoundAlbumsScreen_Loaded(object sender, RoutedEventArgs e)
    {
        _musicClientHelper = new MusicClientHelper(this, BeginLoadingDataFromMusicServer,
            OnParcelReceived);
        _musicClientHelper.Screen.Opened += OnScreenOpened;
    }

    void OnScreenOpened(object sender, EventArgs e)
    {
        // if the required properties were not set correctly before navigating to this screen,
        // this screen is in an error state
        if (Find == null)
        {
            _musicClientHelper.SetErrorState();
            return;
        }

		if (_isDirty)
		{
			HeaderTextBlock.Text = String.Format(_headerFormatString, Find,
                _musicClientHelper.MusicDeviceName);

			// do the same thing we'd do if we were waiting for the music server to become available
			_musicClientHelper.TryToLoadData();
		}
    }

    void BeginLoadingDataFromMusicServer()
    {
        AlbumsListBox.Items.Clear();

        string command = ParsedSyncNodeCommand.Format("Search",
             "RecipientId", XmlConvert.ToString(_musicClientHelper.RecipientId),
             "Find", Find,
             "MaxArtists", "-1",
             "MaxAlbums", "9999",
             "MaxTracks", "-1",
             "GetAlbumArt", "true");

        _musicClientHelper.MusicDeviceNode.ExecuteCommand(command);
    }

    void OnParcelReceived(Guid recipientId, XmlReader reader)
    {
        try
        {
            string artistName = null, albumId = null, albumName = null;
            byte[] albumArtBytes = null;
            foreach (XmlElementInfo element in XmlElementInfo.EnumerateElements(reader)) {
                switch (element.Name)
                {

                case "FoundAlbum":

                    artistName = element.GetRequiredAttribute("ArtistName");
                    albumId = element.GetRequiredAttribute("AlbumId");
                    albumName = element.GetRequiredAttribute("AlbumName");
                    albumArtBytes = null;
					break;

                case "FoundAlbumArt":

                    albumArtBytes = element.GetContentAsBytes();
                    break;

				case "/FoundAlbum":

                    AddAlbumToList(albumId, artistName, albumName, albumArtBytes);
					break;

                case "/DoneSearch":

                    _musicClientHelper.OnDataLoaded();
                    _isDirty = false;
                    break;

                }
            }
        }
        catch (InvalidOperationException ex)
        {
            ClientGlobals.Alert(AlertType.Warning,
                "Invalid reply from server: {0}", ex.Message);
        }
    }

    void AddAlbumToList(string albumId, string artistName, string albumName, byte[] albumArtBytes)
    {
        BitmapImage albumArt;
        if (albumArtBytes != null)
        {
            using (var stream = new MemoryStream(albumArtBytes))
            {
                albumArt = new BitmapImage();
                albumArt.SetSource(stream);
            }
        }
        else
            albumArt = null;

        var buttonFace = new HomeUX.MusicClientLibrary.AlbumButtonFace()
        {
            Tag = albumId,
            AlbumName = String.Format("{0} - {1}", albumName, artistName),
            Height = 210
        };

        if (albumArt != null)
        {
            buttonFace.AlbumArt = albumArt;
        }

        AlbumsListBox.Items.Add(buttonFace);
    }

    void MusicFoundAlbumsScreen_GotFocus(object sender, RoutedEventArgs e)
    {
        AlbumsListBox.Focus();
    }

    private void AlbumsListBox_ItemClick(object sender, ItemClickEventArgs e)
    {
        string albumId = Item.GetUntypedValue(e.Item);

        Screen screen;
        MusicAlbumScreen screenControl;
        _musicClientHelper.FindMusicScreen("Album", out screen, out screenControl);
        screenControl.AlbumId = albumId;
        screenControl.HighlightTrackNumber = -1;
        screen.GoTo();
    }
}

}

